package com.lancer.cloud.engine.util;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.lancer.cloud.common.util.PackageUtils;
import com.lancer.cloud.engine.annotation.CheckStrategy;
import com.lancer.cloud.engine.annotation.Rule;
import com.lancer.cloud.engine.enums.RuleTypeEnum;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;

/**
 * 注解类扫描获取工具类
 *
 * @author caijinbang
 * @date 2019-06-24 15:26
 */
@Slf4j
public class AnnotationUtils {

    /**
     * 通过注解获取规则类(一个value可对应多个)
     * @return <规则代码,规则类名>
     */
    public static Map<String, List<String>> getRuleClasses(RuleTypeEnum ruleType) {
        Map<String, List<String>> data = Maps.newHashMap();

        List<String> classes = PackageUtils.getClassName("com.lancer.cloud.engine");
        if(CollectionUtils.isEmpty(classes)) {
            return data;
        }

        for (String clsName : classes) {
            try {
                Class cls = Class.forName(clsName);
                Rule rule = (Rule) cls.getAnnotation(Rule.class);
                if(rule == null || !Arrays.asList(rule.owner()).contains(ruleType)) {
                    continue;
                }
                String val = rule.value();
                if(data.containsKey(val.trim())) {
                    data.get(val.trim()).add(clsName);
                }else{
                    data.put(val.trim(), Lists.newArrayList(clsName));
                }
            } catch (Exception e) {
                log.error(e.getMessage(), e);
            }
        }
        return data;
    }

    /**
     * 通过注解获取规则类(一个value对应一个)
     * @param annotationClass
     * @return <规则代码,规则类名>
     */
    public static Map<String, String> getCalcClass(Class<? extends Annotation> annotationClass) {
        Map<String, String> data = Maps.newHashMap();
        //获取规则引擎包下的类
        List<String> classes = PackageUtils.getClassName("com.lancer.cloud.engine");
        if(CollectionUtils.isEmpty(classes)) {
            return data;
        }

        for (String clsName : classes) {
            try {
                Class cls = Class.forName(clsName);
                Annotation annotation = cls.getAnnotation(annotationClass);
                if(annotation == null) {
                    continue;
                }
                Method m = annotation.getClass().getDeclaredMethod("value", null);
                String val = (String) m.invoke(annotation, null);
                data.put(val.trim(), clsName);
            } catch (Exception e) {
                log.error(clsName, e);
            }
        }

        return data;
    }

    /**
     * 获取策略注解类
     * @param annotationClass
     * @return
     */
    public static Map<String, String> getStrategyClasses(Class<CheckStrategy> annotationClass) {
        Map<String, String> data = Maps.newHashMap();

        List<String> classes = PackageUtils.getClassName("com.onlyou.engine.data.strategy.impl");
        if(CollectionUtils.isEmpty(classes)) {
            return data;
        }

        for (String clsName : classes) {
            try {
                Class cls = Class.forName(clsName);
                CheckStrategy annotation = (CheckStrategy) cls.getAnnotation(annotationClass);
                if(annotation == null) {
                    continue;
                }
//                RuleTableEnum[] types = annotation.type();
//                if(types.length == 0) {
//                    continue;
//                }
//                for (RuleTableEnum type : types) {
//                    data.put(type, clsName);
//                }
            } catch (ClassNotFoundException e) {
                log.error(e.getMessage(), e);
            }
        }
        return data;
    }
}
